#pragma once

#include "Common.hpp"
#include "Log.hpp"

using namespace LogModule;

const std::string dev = "/dev/null";

void Daemon(int nochdir, int noclose)
{
    signal(SIGCHLD, SIG_IGN); // 忽略子进程信号
    signal(SIGHUP, SIG_IGN);  // 忽略SIGHUP信号

    // 创建子进程
    pid_t pid = fork();
    if (pid > 0) // 父进程退出
    {
        exit(0);
    }

    // 调用创建新会话
    pid_t sid = setsid(); // 创建新会话

    if(nochdir == 0)
    {
        chdir("/"); // 改变工作目录
    }

    if (noclose == 0)
    {
        // 利用null重定向关闭标准文件描述符
        // 打开null文件
        int fd = open(dev.c_str(), O_RDWR);
        if (fd < 0)
        {
            LOG(LogLevel::FATAL) << "open " << dev << "erro, " << "打开null文件失败";
            exit(OPEN_ERR);
        }

        // 重定向标准输入, 标准输出, 标准错误
        dup2(fd, 0);
        dup2(fd, 1);
        dup2(fd, 2);

        // 关闭null文件描述符
        close(fd);
    }
}